<html>
  <head>
    <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>MyBatis_4	多表查询  | 清汤牛肉锅</title>
<meta name="description" content="温故而知新
" />
<link rel="shortcut icon" href="https://ArtZoick.github.io//favicon.ico?v=1572228390311">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.10.0/katex.min.css">
<link rel="stylesheet" href="https://ArtZoick.github.io//styles/main.css">

<script src="https://cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Droid+Serif:400,700">


<script async src="https://www.googletagmanager.com/gtag/js?id=UA-143265163-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-143265163-1');
</script>


  </head>
  <body>
    <div class="main">
      <div class="main-content">
        <div class="site-header">
  <a href="https://ArtZoick.github.io/">
  <img class="avatar" src="https://ArtZoick.github.io//images/avatar.png?v=1572228390311" alt="">
  </a>
  <h1 class="site-title">
    清汤牛肉锅
  </h1>
  <p class="site-description">
    温故而知新

  </p>
  <div class="menu-container">
    
      
        <a href="/" class="menu">
          首页
        </a>
      
    
      
        <a href="/archives" class="menu">
          归档
        </a>
      
    
      
        <a href="/tags" class="menu">
          标签
        </a>
      
    
      
        <a href="/post/about" class="menu">
          关于
        </a>
      
    
      
        <a href="/post/beef" class="menu">
          牛肉锅
        </a>
      
    
  </div>
  <div class="social-container">
    
      
    
      
    
      
    
      
    
      
    
  </div>
</div>

        <div class="post-detail">
          <article class="post">
            <h2 class="post-title">
              MyBatis_4	多表查询 
            </h2>
            <div class="post-info">
              <span>
                2019-07-03
              </span>
              <span>
                14 min read
              </span>
              
                <a href="https://ArtZoick.github.io//tag/framework" class="post-tag">
                  # 框架
                </a>
              
                <a href="https://ArtZoick.github.io//tag/MyBatis" class="post-tag">
                  # MyBatis
                </a>
              
            </div>
            
            <div class="post-content-wrapper">
              <div class="post-content">
                <h2 id="一对一的关系映射">一对一的关系映射</h2>
<h3 id="示例">示例</h3>
<p>查询所有操作,同时获取到用户下所有账户的信息（多表查询常用方法）</p>
<h3 id="sql-语句">sql 语句</h3>
<p>sql 语句查询所有账户的时候同时获得当前账户的所有信息</p>
<pre><code class="language-sql">select u.*,a.id as aid,a.uid,a.money from account a ,user u where u.id=a.uid;
</code></pre>
<p>sql 语句查询所有账户的时候同时获得当前账户的所地址和姓名</p>
<pre><code class="language-sql">select a.*,u.username,u.address from account a ,user u where u.id=a.uid;
</code></pre>
<h3 id="1从表实体应该包含一个主表实体的对象引用">1.	从表实体应该包含一个主表实体的对象引用</h3>
<p>在Account类中</p>
<pre><code class="language-java">//从表实体应该包含一个主表实体的对象引用
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

</code></pre>
<h3 id="2iaccountdao的接口中">2.IAccountDao的接口中</h3>
<pre><code class="language-java">public interface IAccountDao {

    /**
     * 查询所有账户
     * @return
     */
    List&lt;Account&gt; findAll();
}

</code></pre>
<h3 id="3accountdao的mapper中">3.AccountDao的mapper中</h3>
<pre><code class="language-xml">&lt;mapper namespace=&quot;top.zoick.dao.IAccountDao&quot;&gt;
    &lt;!--定义封装account和user的resultMap--&gt;
    &lt;resultMap id=&quot;accountUserMap&quot; type=&quot;account&quot;&gt;
        &lt;id property=&quot;id&quot; column=&quot;aid&quot; /&gt;
        &lt;result property=&quot;uid&quot; column=&quot;uid&quot; /&gt;
        &lt;result property=&quot;money&quot; column=&quot;money&quot; /&gt;
        &lt;!--一对一的关系映射，配置封装user的内容 column中指名从表的外键 property=&quot;user&quot;指的是单个实体类的引用--&gt;
        &lt;association property=&quot;user&quot; column=&quot;uid&quot; javaType=&quot;User&quot;&gt;
            &lt;id property=&quot;id&quot; column=&quot;id&quot;/&gt;
            &lt;result property=&quot;username&quot; column=&quot;username&quot;/&gt;
            &lt;result property=&quot;address&quot; column=&quot;address&quot;/&gt;
            &lt;result property=&quot;sex&quot; column=&quot;sex&quot;/&gt;
            &lt;result property=&quot;birthday&quot; column=&quot;birthday&quot;/&gt;
        &lt;/association&gt;
    &lt;/resultMap&gt;

    &lt;!--IAccountDao的查询所有--&gt;
    &lt;select id=&quot;findAll&quot; resultMap=&quot;accountUserMap&quot;&gt;
          select u.*,a.id as aid,a.uid,a.money from account a ,user u where u.id=a.uid;
    &lt;/select&gt;
&lt;/mapper&gt;
</code></pre>
<p>注意事项中的javaType=“User” 一定要指名主体表的实体类名然后column中指名从表的外键！！</p>
<pre><code class="language-xml">&lt;association property=&quot;user&quot; column=&quot;uid&quot; javaType=&quot;User&quot;&gt;
</code></pre>
<h3 id="4accountdao的测试类中">4.AccountDao的测试类中</h3>
<pre><code class="language-java">@Test
public void findAll(){
    List&lt;Account&gt; accounts = accoutDao.findAll();
    for (Account account:accounts) {
       System.out.println(&quot;每一个account的信息&quot;);
       System.out.println(account);
       System.out.println(account.getUser());
     }
}
</code></pre>
<h3 id="第二种方法是创建一个accountuser类">第二种方法是创建一个AccountUser类</h3>
<p>不建议使用</p>
<hr>
<h2 id="一对多的关系映射">一对多的关系映射</h2>
<h3 id="示例用户和账户">示例：用户和账户</h3>
<p>一个用户可以有多个账户<br>
　　一个账户只能属于一个用户（多个账户也可以属于同一个用户）</p>
<h3 id="步骤">步骤：</h3>
<p>1、建立两张表：用户表 帐户表<br>
　　　　　　让用户表和账户表之前具备一对多的关系：需要使用外键在帐户表上添加<br>
　　2、建立两个实体类：用户实体类和账户实体类<br>
　　　　　　让用户和账户的实体类能体现出来一对多的关系<br>
　　3、配置两个配置文件<br>
　　　　　　用户的配置文件<br>
　　　　　　账户的配置文件<br>
　　4、实现配置：<br>
　　　　　　当我们查询用户的时候，可以同时得到用户下所包含的信息<br>
　　　　　　当我们查询账户时，我们可以同时得到账户所属的用户信息</p>
<h3 id="创建表与相关数据">创建表与相关数据</h3>
<pre><code class="language-sql">CREATE TABLE `account` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `UID` int(11) default NULL COMMENT '用户编号',
  `MONEY` double default NULL COMMENT '金额',
  PRIMARY KEY  (`ID`),
  KEY `FK_Reference_8` (`UID`),
  CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</code></pre>
<h4 id="查询的sql语句">查询的sql语句</h4>
<pre><code class="language-sql">select * from user u left outer join account a on u.id = a.uid
</code></pre>
<p>left join（左连接）是left outer join的简写，返回左表中所有记录和右表中连接字段相等的记录，即返回的记录数和左表的记录数一样</p>
<figure data-type="image" tabindex="1"><img src="https://ArtZoick.github.io//post-images/mybatis/7.png" alt=""></figure>
<h3 id="1主表实体中应该包含从表实体的集合引用">1.主表实体中应该包含从表实体的集合引用</h3>
<p>User类中</p>
<pre><code class="language-java">@Getter
@Setter
@ToString
public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //一对多关系映射，主表实体应该包含从表实体的集合应用
    private List&lt;Account&gt; accounts;

}
</code></pre>
<h3 id="2userdao的接口中">2.UserDao的接口中</h3>
<pre><code class="language-java">//  查询所有用户
 List&lt;User&gt; findAll();
</code></pre>
<h3 id="3userdao的mapper中">3.UserDao的mapper中</h3>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;

&lt;mapper namespace=&quot;top.zoick.dao.IUserDao&quot;&gt;
    &lt;!--定义封装user和account的resultMap type主表实体类--&gt;
    &lt;resultMap id=&quot;userAccountMap&quot; type=&quot;User&quot;&gt;
        &lt;id property=&quot;id&quot; column=&quot;id&quot;&gt;&lt;/id&gt;
        &lt;result property=&quot;username&quot; column=&quot;username&quot;&gt;&lt;/result&gt;
        &lt;result property=&quot;sex&quot; column=&quot;sex&quot;&gt;&lt;/result&gt;
        &lt;result property=&quot;address&quot; column=&quot;address&quot;&gt;&lt;/result&gt;
        &lt;result property=&quot;birthday&quot; column=&quot;birthday&quot;&gt;&lt;/result&gt;
        &lt;!--一对多的关系映射，配置user封装accounts的内容--&gt;
        &lt;!--其中的property指的是从表的集合引用 ofType从表实体类--&gt;
        &lt;collection property=&quot;accounts&quot; ofType=&quot;Account&quot;&gt;
            &lt;id property=&quot;id&quot; column=&quot;aid&quot;&gt;&lt;/id&gt;
            &lt;result property=&quot;uid&quot; column=&quot;uid&quot;&gt;&lt;/result&gt;
            &lt;result property=&quot;money&quot; column=&quot;money&quot;&gt;&lt;/result&gt;
        &lt;/collection&gt;
    &lt;/resultMap&gt;

    &lt;!--配置查询所有  其中id不能乱写必须是dao接口中的方法  resultType写的是实体类的全路径--&gt;
    &lt;select id=&quot;findAll&quot; resultMap=&quot;userAccountMap&quot;&gt;
          select * from user u left outer join account a on u.id = a.uid
    &lt;/select&gt;
&lt;/mapper&gt;
</code></pre>
<p>注意：一对一用的是association，一对多以及多对多用的是collection。</p>
<h3 id="4userdao的测试类中">4.UserDao的测试类中</h3>
<pre><code class="language-java">//查询所有（一个用户下的账号信息）
    @Test
    public  void findAll( ) throws Exception {
        List&lt;User&gt; users = userDao.findAll();
        for (User user:users
             ) {
            System.out.println(&quot;每个用户的信息&quot;);
            System.out.println(user);
            System.out.println(user.getAccounts());
        }
    }
</code></pre>
<h3 id="5成功运行实现上述功能">5.成功运行（实现上述功能）</h3>
<figure data-type="image" tabindex="2"><img src="https://ArtZoick.github.io//post-images/mybatis/8.png" alt=""></figure>
<h2 id="多对多的关系映射">多对多的关系映射</h2>
<h3 id="示例用户与角色">示例：用户与角色</h3>
<p>一个用户可以有多个角色<br>
一个角色可以赋予多个用户</p>
<h3 id="步骤-2">步骤：</h3>
<p>1、建立两张表：用户表  用户表<br>
　　　　　　让用户和角色表具有多对多的关系。需要使用中间表，中间表中包含各自的主键，在中间表中是外键。<br>
　　2、建立两个实体类：用户实体类和角色实体类<br>
　　　　　　让用户和角色的实体类能体现出来多对多的关系<br>
　　　　　　各自包含对方一个集合引用<br>
　　3、配置两个配置文件<br>
　　　　　　用户的配置文件<br>
　　　　　　角色的配置文件<br>
　　4、实现配置：<br>
　　　　　　当我们查询用户的时候，可以同时得到用户下所包含角色的信息<br>
　　　　　　当我们查询角色时，我们可以同时得到角色所赋予的用户信息</p>
<h3 id="表设计">表设计</h3>
<h4 id="表设置如下">表设置如下：</h4>
<pre><code class="language-sql">CREATE TABLE `role` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',
  `ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',
  PRIMARY KEY  (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `user_role` (
  `UID` int(11) NOT NULL COMMENT '用户编号',
  `RID` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY  (`UID`,`RID`),
  KEY `FK_Reference_10` (`RID`),
  CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
  CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</code></pre>
<pre><code class="language-sql">insert  into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校');
insert  into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);
</code></pre>
<h4 id="表数据如下">表数据如下：</h4>
<figure data-type="image" tabindex="3"><img src="https://ArtZoick.github.io//post-images/mybatis/9.png" alt=""></figure>
<figure data-type="image" tabindex="4"><img src="https://ArtZoick.github.io//post-images/mybatis/9_1.png" alt=""></figure>
<figure data-type="image" tabindex="5"><img src="https://ArtZoick.github.io//post-images/mybatis/9_2.png" alt=""></figure>
<h4 id="sql语句多表外链接查询语句">sql语句(多表外链接查询语句)</h4>
<pre><code class="language-sql">select u.*, r.id as rid,r.role_name,r.role_desc from role r   
left outer join user_role ur on r.id = ur.rid   
left outer join user u on u.id=ur.uid  
</code></pre>
<p>注意其中每行末尾的空格<br>
**目的：**为了查询角色下的用户信息<br>
**步骤：**以role表（别名）为主表，左外连接user_role表（别名ur,此表为中间表），连接条件r.id = ur.rid 。<br>
再以这两个表组合的表左外连接user表，连接条件u.id=ur.uid 。</p>
<p><strong>注意：</strong><a href="https://jingyan.baidu.com/article/60ccbceb9578f164cab197f4.html">数据库连接（内链接，外连接（左连接，右连接）</a></p>
<h4 id="查询结果">查询结果</h4>
<figure data-type="image" tabindex="6"><img src="https://ArtZoick.github.io//post-images/mybatis/10.png" alt=""></figure>
<h3 id="1一个实体表中包含另一个实体表的集合引用">1.一个实体表中包含另一个实体表的集合引用</h3>
<p>由于是多对多的关系所有不分从表和主表</p>
<pre><code class="language-java">@Setter
@Getter
@ToString
public class Role implements Serializable {

    private Integer roleId;
    private String roleName;
    private String roleDesc;

    /**
     * 多对多的关系映射：一个角色可以赋予多个用户
     */
    private List&lt;User&gt; users;
}

</code></pre>
<h3 id="2iroledao接口中定义该方法">2.IRoleDao接口中定义该方法</h3>
<pre><code class="language-java">public interface IRoleDao {
    /**
     * 查询所有角色
     * @return
     */
    List&lt;Role&gt; findAll();
}

</code></pre>
<h3 id="3iroledao的mapper中">3.IRoleDao的mapper中</h3>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;
&lt;mapper namespace=&quot;top.zoick.dao.IRoleDao&quot;&gt;
    &lt;!--定义role表的resultmap--&gt;
    &lt;resultMap id=&quot;roleMap&quot; type=&quot;role&quot;&gt;
        &lt;!--此处id的column由于sql语句中将role表中的id改为rid，故column也要变为rid--&gt;
        &lt;id property=&quot;roleId&quot; column=&quot;rid&quot;/&gt;
        &lt;result property=&quot;roleName&quot; column=&quot;role_name&quot;/&gt;
        &lt;result property=&quot;roleDesc&quot; column=&quot;role_desc&quot;/&gt;
        &lt;collection property=&quot;users&quot; ofType=&quot;user&quot;&gt;
            &lt;id column=&quot;id&quot; property=&quot;id&quot;/&gt;
            &lt;result column=&quot;username&quot; property=&quot;username&quot;/&gt;
            &lt;result column=&quot;address&quot; property=&quot;address&quot;/&gt;
            &lt;result column=&quot;sex&quot; property=&quot;sex&quot;/&gt;
            &lt;result column=&quot;birthday&quot; property=&quot;birthday&quot;/&gt;
        &lt;/collection&gt;
    &lt;/resultMap&gt;

    &lt;!--查询所有--&gt;
    &lt;select id=&quot;findAll&quot; resultMap=&quot;roleMap&quot;&gt;
        select u.*, r.id as rid,r.role_name,r.role_desc from role r
         left outer join user_role ur on r.id=ur.rid
         left outer join user u on u.id = ur.uid
    &lt;/select&gt;
&lt;/mapper&gt;
</code></pre>
<h3 id="4roledao的测试类中">4.RoleDao的测试类中</h3>
<pre><code class="language-java">@Test
    public void findAll(){
        List&lt;Role&gt; roles  = roleDao.findAll();
        for (Role role:roles
             ) {
            System.out.println(&quot;=====每个角色的信息=====&quot;);
            System.out.println(role);
            System.out.println(role.getUsers());
        }
    }
</code></pre>
<h3 id="5成功运行实现上述功能-2">5.成功运行（实现上述功能）</h3>
<h3 id=""><img src="https://ArtZoick.github.io//post-images/mybatis/10_1.png" alt=""></h3>
<h3 id="同理可得用户的全部信息与用户的角色">=<mark>同理可得用户的全部信息与用户的角色</mark>=</h3>
<h4 id="sql语句">sql语句</h4>
<pre><code class="language-sql">select u.*, r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur on u.id = ur.uid
left outer join role r on r.id=ur.rid
</code></pre>
<h3 id="6实体类user包含对accounts的引用">6.实体类User包含对Accounts的引用</h3>
<pre><code class="language-java">@Getter
@Setter
@ToString
public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    
    //实体类User包含对Accounts的引用
    private List&lt;Role&gt; roles;
}

</code></pre>
<h3 id="7userdao的接口中定义该方法">7.UserDao的接口中定义该方法</h3>
<pre><code class="language-java">  //  查询所有
    List&lt;User&gt; findAll();
</code></pre>
<h3 id="8userdao的mapper中">8.UserDao的mapper中</h3>
<pre><code class="language-xml"> &lt;resultMap id=&quot;userMap&quot; type=&quot;user&quot;&gt;

        &lt;id property=&quot;id&quot; column=&quot;id&quot;&gt;&lt;/id&gt;
        &lt;result property=&quot;username&quot; column=&quot;username&quot;&gt;&lt;/result&gt;
        &lt;result property=&quot;address&quot; column=&quot;address&quot;&gt;&lt;/result&gt;
        &lt;result property=&quot;sex&quot; column=&quot;sex&quot;&gt;&lt;/result&gt;
        &lt;result property=&quot;birthday&quot; column=&quot;birthday&quot;&gt;&lt;/result&gt;


        &lt;collection property=&quot;roles&quot; ofType=&quot;role&quot;&gt;
            &lt;id property=&quot;roleId&quot; column=&quot;rid&quot;&gt;&lt;/id&gt;
            &lt;result property=&quot;roleName&quot; column=&quot;role_name&quot;&gt;&lt;/result&gt;
            &lt;result property=&quot;roleDesc&quot; column=&quot;role_desc&quot;&gt;&lt;/result&gt;
        &lt;/collection&gt;
    &lt;/resultMap&gt;


    &lt;select id=&quot;findAll&quot; resultMap=&quot;userMap&quot;&gt;
       select u.*,r.id as rid,r.role_name,r.role_desc from user u

      left outer join user_role ur on u.id = ur.uid

       left outer join role r on r.id=ur.rid
    &lt;/select&gt;

</code></pre>
<h3 id="9userdao的测试类中">9.UserDao的测试类中</h3>
<pre><code> @Test
    public  void findAll( ) throws Exception {

        List&lt;User&gt; users = userDao.findAll();
        for (User user:users
             ) {
            System.out.println(&quot;====每个用户的信息====&quot;);
            System.out.println(user);
            System.out.println(user.getRoles());
        }

    }
</code></pre>
<h3 id="10成功运行实现上述功能">10.成功运行（实现上述功能）</h3>
<hr>
<h1 id="jndi">JNDI</h1>
<p>JNDI是 Java 命名与目录接口（Java Naming and Directory Interface），在J2EE规范中是重要的规范之一。</p>
<figure data-type="image" tabindex="7"><img src="https://ArtZoick.github.io//post-images/mybatis/11.png" alt=""></figure>
<hr>
<h2 id="源码点这里">源码：<a href="https://github.com/ArtZoick/MyBatis">点🐔这里</a></h2>

              </div>
              <div class="toc-container">
                <ul class="markdownIt-TOC">
<li>
<ul>
<li><a href="#%E4%B8%80%E5%AF%B9%E4%B8%80%E7%9A%84%E5%85%B3%E7%B3%BB%E6%98%A0%E5%B0%84">一对一的关系映射</a>
<ul>
<li><a href="#%E7%A4%BA%E4%BE%8B">示例</a></li>
<li><a href="#sql-%E8%AF%AD%E5%8F%A5">sql 语句</a></li>
<li><a href="#1%E4%BB%8E%E8%A1%A8%E5%AE%9E%E4%BD%93%E5%BA%94%E8%AF%A5%E5%8C%85%E5%90%AB%E4%B8%80%E4%B8%AA%E4%B8%BB%E8%A1%A8%E5%AE%9E%E4%BD%93%E7%9A%84%E5%AF%B9%E8%B1%A1%E5%BC%95%E7%94%A8">1.	从表实体应该包含一个主表实体的对象引用</a></li>
<li><a href="#2iaccountdao%E7%9A%84%E6%8E%A5%E5%8F%A3%E4%B8%AD">2.IAccountDao的接口中</a></li>
<li><a href="#3accountdao%E7%9A%84mapper%E4%B8%AD">3.AccountDao的mapper中</a></li>
<li><a href="#4accountdao%E7%9A%84%E6%B5%8B%E8%AF%95%E7%B1%BB%E4%B8%AD">4.AccountDao的测试类中</a></li>
<li><a href="#%E7%AC%AC%E4%BA%8C%E7%A7%8D%E6%96%B9%E6%B3%95%E6%98%AF%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAaccountuser%E7%B1%BB">第二种方法是创建一个AccountUser类</a></li>
</ul>
</li>
<li><a href="#%E4%B8%80%E5%AF%B9%E5%A4%9A%E7%9A%84%E5%85%B3%E7%B3%BB%E6%98%A0%E5%B0%84">一对多的关系映射</a>
<ul>
<li><a href="#%E7%A4%BA%E4%BE%8B%E7%94%A8%E6%88%B7%E5%92%8C%E8%B4%A6%E6%88%B7">示例：用户和账户</a></li>
<li><a href="#%E6%AD%A5%E9%AA%A4">步骤：</a></li>
<li><a href="#%E5%88%9B%E5%BB%BA%E8%A1%A8%E4%B8%8E%E7%9B%B8%E5%85%B3%E6%95%B0%E6%8D%AE">创建表与相关数据</a>
<ul>
<li><a href="#%E6%9F%A5%E8%AF%A2%E7%9A%84sql%E8%AF%AD%E5%8F%A5">查询的sql语句</a></li>
</ul>
</li>
<li><a href="#1%E4%B8%BB%E8%A1%A8%E5%AE%9E%E4%BD%93%E4%B8%AD%E5%BA%94%E8%AF%A5%E5%8C%85%E5%90%AB%E4%BB%8E%E8%A1%A8%E5%AE%9E%E4%BD%93%E7%9A%84%E9%9B%86%E5%90%88%E5%BC%95%E7%94%A8">1.主表实体中应该包含从表实体的集合引用</a></li>
<li><a href="#2userdao%E7%9A%84%E6%8E%A5%E5%8F%A3%E4%B8%AD">2.UserDao的接口中</a></li>
<li><a href="#3userdao%E7%9A%84mapper%E4%B8%AD">3.UserDao的mapper中</a></li>
<li><a href="#4userdao%E7%9A%84%E6%B5%8B%E8%AF%95%E7%B1%BB%E4%B8%AD">4.UserDao的测试类中</a></li>
<li><a href="#5%E6%88%90%E5%8A%9F%E8%BF%90%E8%A1%8C%E5%AE%9E%E7%8E%B0%E4%B8%8A%E8%BF%B0%E5%8A%9F%E8%83%BD">5.成功运行（实现上述功能）</a></li>
</ul>
</li>
<li><a href="#%E5%A4%9A%E5%AF%B9%E5%A4%9A%E7%9A%84%E5%85%B3%E7%B3%BB%E6%98%A0%E5%B0%84">多对多的关系映射</a>
<ul>
<li><a href="#%E7%A4%BA%E4%BE%8B%E7%94%A8%E6%88%B7%E4%B8%8E%E8%A7%92%E8%89%B2">示例：用户与角色</a></li>
<li><a href="#%E6%AD%A5%E9%AA%A4-2">步骤：</a></li>
<li><a href="#%E8%A1%A8%E8%AE%BE%E8%AE%A1">表设计</a>
<ul>
<li><a href="#%E8%A1%A8%E8%AE%BE%E7%BD%AE%E5%A6%82%E4%B8%8B">表设置如下：</a></li>
<li><a href="#%E8%A1%A8%E6%95%B0%E6%8D%AE%E5%A6%82%E4%B8%8B">表数据如下：</a></li>
<li><a href="#sql%E8%AF%AD%E5%8F%A5%E5%A4%9A%E8%A1%A8%E5%A4%96%E9%93%BE%E6%8E%A5%E6%9F%A5%E8%AF%A2%E8%AF%AD%E5%8F%A5">sql语句(多表外链接查询语句)</a></li>
<li><a href="#%E6%9F%A5%E8%AF%A2%E7%BB%93%E6%9E%9C">查询结果</a></li>
</ul>
</li>
<li><a href="#1%E4%B8%80%E4%B8%AA%E5%AE%9E%E4%BD%93%E8%A1%A8%E4%B8%AD%E5%8C%85%E5%90%AB%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%AE%9E%E4%BD%93%E8%A1%A8%E7%9A%84%E9%9B%86%E5%90%88%E5%BC%95%E7%94%A8">1.一个实体表中包含另一个实体表的集合引用</a></li>
<li><a href="#2iroledao%E6%8E%A5%E5%8F%A3%E4%B8%AD%E5%AE%9A%E4%B9%89%E8%AF%A5%E6%96%B9%E6%B3%95">2.IRoleDao接口中定义该方法</a></li>
<li><a href="#3iroledao%E7%9A%84mapper%E4%B8%AD">3.IRoleDao的mapper中</a></li>
<li><a href="#4roledao%E7%9A%84%E6%B5%8B%E8%AF%95%E7%B1%BB%E4%B8%AD">4.RoleDao的测试类中</a></li>
<li><a href="#5%E6%88%90%E5%8A%9F%E8%BF%90%E8%A1%8C%E5%AE%9E%E7%8E%B0%E4%B8%8A%E8%BF%B0%E5%8A%9F%E8%83%BD-2">5.成功运行（实现上述功能）</a></li>
<li><a href="#">!</a></li>
<li><a href="#%E5%90%8C%E7%90%86%E5%8F%AF%E5%BE%97%E7%94%A8%E6%88%B7%E7%9A%84%E5%85%A8%E9%83%A8%E4%BF%A1%E6%81%AF%E4%B8%8E%E7%94%A8%E6%88%B7%E7%9A%84%E8%A7%92%E8%89%B2">===同理可得用户的全部信息与用户的角色===</a>
<ul>
<li><a href="#sql%E8%AF%AD%E5%8F%A5">sql语句</a></li>
</ul>
</li>
<li><a href="#6%E5%AE%9E%E4%BD%93%E7%B1%BBuser%E5%8C%85%E5%90%AB%E5%AF%B9accounts%E7%9A%84%E5%BC%95%E7%94%A8">6.实体类User包含对Accounts的引用</a></li>
<li><a href="#7userdao%E7%9A%84%E6%8E%A5%E5%8F%A3%E4%B8%AD%E5%AE%9A%E4%B9%89%E8%AF%A5%E6%96%B9%E6%B3%95">7.UserDao的接口中定义该方法</a></li>
<li><a href="#8userdao%E7%9A%84mapper%E4%B8%AD">8.UserDao的mapper中</a></li>
<li><a href="#9userdao%E7%9A%84%E6%B5%8B%E8%AF%95%E7%B1%BB%E4%B8%AD">9.UserDao的测试类中</a></li>
<li><a href="#10%E6%88%90%E5%8A%9F%E8%BF%90%E8%A1%8C%E5%AE%9E%E7%8E%B0%E4%B8%8A%E8%BF%B0%E5%8A%9F%E8%83%BD">10.成功运行（实现上述功能）</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#jndi">JNDI</a>
<ul>
<li><a href="#%E6%BA%90%E7%A0%81%E7%82%B9%E8%BF%99%E9%87%8C">源码：点🐔这里</a></li>
</ul>
</li>
</ul>

              </div>
            </div>
          </article>
        </div>

        
          <div class="next-post">
            <div class="next">下一篇</div>
            <a href="https://ArtZoick.github.io//post/MyBatis_3">
              <h3 class="post-title">
                 MyBatis_3	连接池、事务控制、动态SQL
              </h3>
            </a>
          </div>
        

        
          
            <link rel="stylesheet" href="https://unpkg.com/gitalk/dist/gitalk.css">
<script src="https://unpkg.com/gitalk/dist/gitalk.min.js"></script>

<div id="gitalk-container"></div>

<script>

  var gitalk = new Gitalk({
    clientID: 'a2471d09bddb5be481ee',
    clientSecret: '05d427fb27f873cfabace27b9f042f2c7f23000f',
    repo: 'ArtZoick.github.io',
    owner: 'ArtZoick',
    admin: ['ArtZoick'],
    id: (location.pathname).substring(0, 49),      // Ensure uniqueness and length less than 50
    distractionFreeMode: false  // Facebook-like distraction free mode
  })

  gitalk.render('gitalk-container')

</script>

          

          
        

        <div class="site-footer">
  <a href="https://zhidao.baidu.com/question/1867120235416383707.html" target="_blank" onclick="alert('盲生，你发现了华点！');">学习强国</a>

<!--Tido对话插件-->
<script src="//code.tidio.co/5fh6jaqvluqj8jjuf5zlqrf5tlzpktnx.js"></script>
<style>
.text-popup {
    animation: textPopup 1s;
    color: red;
    user-select: none;
    white-space: nowrap;
    position: absolute;
    z-index: 99;
}
@keyframes textPopup {
    0%, 100% {
        opacity: 0;
    }
    5% {
        opacity: 1;
    }
    100% {
        transform: translateY(-50px);    
    }
}
</style>
<script type="text/javascript" src="https://cdn.bootcss.com/canvas-nest.js/1.0.1/canvas-nest.min.js">
!function(){function n(n,e,t){return n.getAttribute(e)||t}function e(n){return document.getElementsByTagName(n)}
function t(){var t=e("script"),o=t.length,i=t[o-1];return{l:o,z:n(i,"zIndex",-1),o:n(i,"opacity",.5),c:n(i,"color","0,0,0")
,n:n(i,"count",99)}}function o(){a=m.width=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidt
h,c=m.height=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}function i(){r.clearRect
(0,0,a,c);var n,e,t,o,m,l;s.forEach(function(i,x){for(i.x+=i.xa,i.y+=i.ya,i.xa*=i.x>a||i.x<0?-1:1,i.ya*=i.y>c||i.y<0?-1:1,r.
fillRect(i.x-.5,i.y-.5,1,1),e=x+1;e<u.length;e++)n=u[e],null!==n.x&&null!==n.y&&(o=i.x-n.x,m=i.y-n.y,l=o*o+m*m,l<n.max&&(n===
y&&l>=n.max/2&&(i.x-=.03*o,i.y-=.03*m),t=(n.max-l)/n.max,r.beginPath(),r.lineWidth=t/2,r.strokeStyle="rgba("+d.c+","+(t+.2)+")
",r.moveTo(i.x,i.y),r.lineTo(n.x,n.y),r.stroke()))}),x(i)}var a,c,u,m=document.createElement("canvas"),d=t(),l="c_n"+d.l,r=m.
getContext("2d"),x=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.
oRequestAnimationFrame||window.msRequestAnimationFrame||function(n){window.setTimeout(n,1e3/45)},w=Math.random,y={x:null,y:nul
l,max:2e4};m.id=l,m.style.cssText="position:fixed;top:0;left:0;z-index:"+d.z+";opacity:"+d.o,e("body")[0].appendChild(m),o(),
window.οnresize=o,window.οnmοusemοve=function(n){n=n||window.event,y.x=n.clientX,y.y=n.clientY},window.οnmοuseοut=function(){y
.x=null,y.y=null};for(var s=[],f=0;d.n>f;f++){var h=w()*a,g=w()*c,v=2*w()-1,p=2*w()-1;s.push({x:h,y:g,xa:v,ya:p,max:6e3})}u=
s.concat([y]),setTimeout(function(){i()},100)}();
</script>

<!--鼠标点击-->
<!--富强-->
<script type="text/javascript"> 
/* 鼠标特效 */ 
var a_idx = 0; 
jQuery(document).ready(function($) { 
    $("body").click(function(e) { 
        var a = new Array("富强", "民主", "文明", "和谐", "自由", "平等", "公正" ,"法治", "爱国", "敬业", "诚信", "友善"); 
        var $i = $("<span/>").text(a[a_idx]); 
        a_idx = (a_idx + 1) % a.length; 
        var x = e.pageX, 
        y = e.pageY; 
        $i.css({ 
            "z-index": 999, 
            "top": y - 20, 
            "left": x, 
            "position": "absolute", 
            "font-weight": "bold", 
            "color": "#ff6651" 
        }); 
        $("body").append($i); 
        $i.animate({ 
            "top": y - 180, 
            "opacity": 0 
        }, 
        1500, 
        function() { 
            $i.remove(); 
        }); 
    }); 
}); 
</script>
<!--edn--富强--> | 
  <a class="rss" href="https://ArtZoick.github.io//atom.xml" target="_blank">RSS</a>
</div>

<script>
  hljs.initHighlightingOnLoad()

  let mainNavLinks = document.querySelectorAll(".markdownIt-TOC a");

  // This should probably be throttled.
  // Especially because it triggers during smooth scrolling.
  // https://lodash.com/docs/4.17.10#throttle
  // You could do like...
  // window.addEventListener("scroll", () => {
  //    _.throttle(doThatStuff, 100);
  // });
  // Only not doing it here to keep this Pen dependency-free.

  window.addEventListener("scroll", event => {
    let fromTop = window.scrollY;

    mainNavLinks.forEach((link, index) => {
      let section = document.getElementById(decodeURI(link.hash).substring(1));
      let nextSection = null
      if (mainNavLinks[index + 1]) {
        nextSection = document.getElementById(decodeURI(mainNavLinks[index + 1].hash).substring(1));
      }
      console.log('section.offsetHeight', section.offsetHeight);
      if (section.offsetTop <= fromTop) {
        if (nextSection) {
          if (nextSection.offsetTop > fromTop) {
            link.classList.add("current");
          } else {
            link.classList.remove("current");    
          }
        } else {
          link.classList.add("current");
        }
      } else {
        link.classList.remove("current");
      }
    });
  });

</script>

      </div>
    </div>
  </body>
</html>
